package nezumi.state;

import java.util.HashMap;
import java.util.Map;
import java.util.Observable;

import ciberIF.beaconMeasure;

import nezumi.Constants;

public class SensorState extends Observable {

	public static final String IR_ALL = "IR_ALL", IR_LFT = "IR_LFT",
			IR_FRT = "IR_FRT", IR_RGT = " IR_RGT", COMPASS = "COMPASS",
			BEACON = "BEACON", GROUND = "GROUND", BUMPER = "BUMPER";
	private static final double cutoff = Constants.IR_CUTOFF;

	private final Map<String, Double> smap;
	private final State state;

	public Map<String, Double> getState() {
		return smap;
	}

	public SensorState(State state) {

		assert state != null : "state = " + state;

		this.state = state;

		smap = new HashMap<String, Double>();

		smap.put(IR_LFT, 0d);
		smap.put(IR_RGT, 0d);
		smap.put(IR_FRT, 0d);
		smap.put(COMPASS, 0d);
		// because 0 means we're at the target
		smap.put(GROUND, 1d);
		smap.put(BUMPER, 0d);
		// for all beacons
		for (int i = 0; i < Constants.N_TARGETS; i++)
			smap.put(BEACON + i, 0d);
	}

	public void batchUpdateIRSensors(final double left, final double front,
			final double right) {

		smap.put(IR_LFT, left);
		smap.put(IR_FRT, front);
		smap.put(IR_RGT, right);

		// we shall only process if we have at least one sensor above the cutoff
		// threshold
		if (left >= cutoff || front >= cutoff || right >= cutoff) {
			// notify the changes
			this.setChanged();
			this.notifyObservers(IR_ALL);
			this.clearChanged();
		}
	}

	public double getSensor(String sensor) {
		return smap.get(sensor);
	}

	public double setSensor(String sensor, double value) {
		return smap.put(sensor, value);
	}

	public void updateGroundSensor(double value) {
		smap.put(GROUND, value);
		if (value != -1 && (int) value == this.state.getPlanner().getTargetId()) { // we
																					// have
																					// a
			// winner
			this.setChanged();
			this.notifyObservers(GROUND);
			this.clearChanged();
		}
	}

	public void updateBeaconSensor(final beaconMeasure bm, final int idx) {
		if (bm.beaconVisible) {
			this.smap.put(BEACON + idx, bm.beaconDir);
			// notify the changes
			this.setChanged();
			this.notifyObservers(new Integer(idx));
			this.clearChanged();
		} else
			this.smap.put(BEACON + idx, 0d);
	}
}
